package process
import (
	"fmt"
	"go_code/projectExec2/common/message"
	"encoding/json"
	"go_code/projectExec2/server/utils"
	"go_code/projectExec2/server/model"
	"net"
)

type UserProcess struct{
	Conn net.Conn
	//表明该连接是哪个user的
	UserId int
}

//编写一个通知所有在线用户的方法
func (this *UserProcess)NotifyOthersOnlineUser(userId int){
	//遍历onlineUsers ,然后一个个发送 NotifyUserStatusMes
	for id,up := range userMgr.onlineUsers{
		if id == userId{
			continue
		}
		//开始通知
		up.NotifyMeOnline(userId)
	}
}
//通知方法
func (this *UserProcess)NotifyMeOnline(userId int){
	//开始组装NotifyUserStatusMes消息
	var mes message.Message
	mes.Type = message.NotifyUserStatusMesType
	 
	var notifyUserStatusMes message.NotifyUserStatusMes
	notifyUserStatusMes.UserId = userId
	notifyUserStatusMes.Status = message.UserOnline

	//将notifyUserStatusMes进行序列化
	data ,err := json.Marshal(notifyUserStatusMes)
	if err != nil{
		fmt.Println("NotifyMeOnline json Marshal Error : ",err)
		return
	}
	//将序列化后的notifyUserStatusMes赋值给mes.Data
	mes.Data = string(data)
	//再次对mes进行序列化
	data ,err = json.Marshal(mes)
	if err != nil{
		fmt.Println("NotifyMeOnline json Marshal Error : ",err)
		return
	}
	//创建transfer实例来发送
	tf := &utils.Transfer{
		Conn : this.Conn,
	}
	err = tf.WritePkg(data)
	if err != nil{
		fmt.Println("NotifyMeOnline WritePkg Error : ",err)
		return
	}
}

//编写一个函数ServerProcessLogin函数，专门处理登录请求
func (this *UserProcess)ServerProcessLogin(mes *message.Message) (err error){
	//核心代码：
	//1、先从mes中取出mes.Data，并且直接反序列化成LoginMes
	var loginMes message.LoginMes
	err = json.Unmarshal([]byte(mes.Data),&loginMes)
	if err != nil{
		fmt.Println("json.Unmarshal fail err :",err)
		return
	}
	//先声明一个resMessage
	var resMes message.Message
	resMes.Type = message.LoginResMesType
	//在声明一个LoginResMes
	var loginResMes message.LoginResMes
	
	//要通过redis数据库完成用户校验
	//1、使用model.MyUserDao进行校验
	user,err2 := model.MyUserDao.Login(loginMes.UserId,loginMes.UserPwd)
	if err2 != nil{
		//判断具体错误信息
		if err2 == model.ERROR_USER_NOTEXISTS{
			loginResMes.Code = 500
			loginResMes.Error = err2.Error()
		}else if err2 == model.ERROR_USER_PWD{
			loginResMes.Code = 403
			loginResMes.Error = err2.Error()
		}else{
			loginResMes.Code = 505
			loginResMes.Error = "服务器内部错误~"
		}	
	}else{
		loginResMes.Code = 200
		fmt.Printf("%s登录成功~\n",user.UserName)

		//用户已经登录成功，就把它放进onlineUser里
		this.UserId = loginMes.UserId
		userMgr.AddonlineUser(this)
		
		//通知其他在线用户我上线了
		this.NotifyOthersOnlineUser(loginMes.UserId)

		//将当前在线用户的id，放入到loginResMes.UsersId
		//遍历 userMgr.onlineUsers
		for id,_ := range userMgr.onlineUsers{
			loginResMes.UsersId = append(loginResMes.UsersId,id)
		}
	}

	//将loginResMes序列化
	data,err := json.Marshal(loginResMes)
	if err != nil{
		fmt.Println("json.Marshal fail Err:",err)
		return
	} 
	resMes.Data = string(data)
	//将resMes序列化，然后准备发送
	data,err = json.Marshal(resMes)
	if err != nil{
		fmt.Println("json.Marshal fail Err:",err)
		return
	} 
	//发送登录结果
	//因为使用了分层模式（mvc）
	tf := &utils.Transfer{
		Conn : this.Conn,
	}
	err =tf.WritePkg(data)
	return 
}
//编写一个函数ServerProcessRegister函数，专门处理注册请求
func (this *UserProcess)ServerProcessRegister(mes *message.Message) (err error){
	//核心代码：
	//1、先从mes中取出mes.Data，并且直接反序列化成RegisterMes
	var registerMes message.RegisterMes
	err = json.Unmarshal([]byte(mes.Data),&registerMes)
	if err != nil{
		fmt.Println("json.Unmarshal fail err :",err)
		return
	}
	//先声明一个resMessage
	var resMes message.Message
	resMes.Type = message.RegisterResMesType
	//在声明一个RegisterResMes
	var registerResMes message.RegisterResMes

	//要通过redis数据库完成用户注册
	//1、使用model.MyUserDao进行
	err2 := model.MyUserDao.Register(&registerMes.User)
	if err2 != nil{
		//判断具体错误信息
		if err2 == model.ERROR_USER_EXISTS{
			registerResMes.Code = 500
			registerResMes.Error = err2.Error()
		}else{
			registerResMes.Code = 505
			registerResMes.Error = "服务器内部错误~"
		}	
	}else{
		registerResMes.Code = 200
		fmt.Println("注册成功~")
	}

	//将registerResMes序列化
	data,err := json.Marshal(registerResMes)
	if err != nil{
		fmt.Println("json.Marshal fail Err:",err)
		return
	} 
	resMes.Data = string(data)
	//将resMes序列化，然后准备发送
	data,err = json.Marshal(resMes)
	if err != nil{
		fmt.Println("json.Marshal fail Err:",err)
		return
	} 
	//发送注册结果
	//因为使用了分层模式（mvc）
	tf := &utils.Transfer{
		Conn : this.Conn,
	}
	err =tf.WritePkg(data)
	return 
}
